#include "thermalcam.h"


static RT::Worker *WorkerPtr = NULL;

static std::string AlarmPath_local = "null";	//报警图像本地路径
static char* _ImgBuff = NULL;  //报警图像的内存指针
static int _ImageBuffSize = 1024;  //报警图像的内存大小

static NET_DVR_DEVICEINFO_V40 _StruDeviceInfoV40 = {0}; //device info
static LONG _LUserID;            //用户  LONG = int
static DWORD DwChannel = 2;  //热成像通道


//save img into charBuff
BOOL CALLBACK MessageCallback3_imgCharBuff(LONG lCommand, NET_DVR_ALARMER *pAlarmer, char *pAlarmInfo, DWORD dwBufLen, void* pUser);

//real temp info and send img
void CALLBACK GetThermInfoCallback_tcp(DWORD dwType, void* lpBuffer, DWORD dwBufLen, void* pUserData) ;
	static int SendTempImgInterval = 1;
	static int SendTempImgcond = 0;
	static bool IsSendRealThermalImg = false;

std::string getImageName(const std::string imgType);
void deleteFile(const string filePath);

ThermalCamera::ThermalCamera(const ThermalCameraArgs args):
				m_selfName("null"),
                mhckLibDir("null"),
				m_fAlarmVal(80),
				m_fAlertVal(40),
				m_rule(0),
				m_imageBuffSize(10240),
				m_realtemp_interval(3),
				mb_alarmDetect(true),
				mb_realTempDetect(true),
				mIsSendRealThermalImg(true),	
				m_sendImgInterval(10),
				m_setThermalSysParams(false)
{
	if( !args.workerPtr)
	{
		printf("*** error: workerPtr is NULL\n");
		exit(-1);
	}
	m_workerPtr = args.workerPtr;
	WorkerPtr = args.workerPtr;
	std::string exePath;
	UtilsTools::mget_exe_path(exePath, 2);

	mhckLibDir = exePath+"lib/";           // ini.readstring(sSection, "HCK_LIB_DIR", "error", dwSize);
	
	ruitu::IniFile ini(args.iniPath.c_str());
	unsigned int dwSize = 0;
	char sSection[16] = "THERMAL";

	//get robotselt name
	m_selfName = m_workerPtr->mId;
	//get robot name 
	strncpy((char*)m_channelName,  m_selfName.c_str(), sizeof(m_channelName)/sizeof(char) );
	//<<<
	
	//camera device param 
	mIP = ini.readstring(sSection, "DeviceAddress", "error", dwSize);
	mPort = ini.readinteger(sSection, "DevicePort", 0);
	mUserName = ini.readstring(sSection, "UserName", "error", dwSize); 
	mPassword = ini.readstring(sSection, "Password", "error", dwSize);
	DwChannel = ini.readinteger(sSection, "Channel", 0);
	m_rule = ini.readinteger(sSection, "Rule", 0);
	//<<<

	mIsSendRealThermalImg = ini.readbool(sSection, "IsSendThermalInfoImg");
	IsSendRealThermalImg = mIsSendRealThermalImg;

	m_imageBuffSize = ini.readinteger(sSection, "ImageBuffSize", 10240);
	_ImageBuffSize = m_imageBuffSize;
	_ImgBuff = new char[_ImageBuffSize];

	m_sendImgInterval = ini.readinteger(sSection, "SendThermalInfoImgInterval", 1);
	SendTempImgInterval = m_sendImgInterval;

	AlarmPath_local = exePath+"tempPictures";   //ini.readstring(sSection, "AlarmPath_local", "error", dwSize);
	if(access(AlarmPath_local.c_str(),  F_OK) != 0){
		string commandMkdir = "";
		commandMkdir = "mkdir -m 777 -p " + AlarmPath_local;
		const int sysres = system(commandMkdir.c_str());
		if (sysres != 0){
			m_workerPtr->m_logerPtr->m_WARNING(commandMkdir+" 执行失败");
		}
		if(access(AlarmPath_local.c_str(),  F_OK) != 0){
			m_workerPtr->m_logerPtr->m_WARNING("AlarmPath_local don't exist !!!\n");
			exit(-1);
		}
	}

	m_setThermalSysParams = ini.readbool(sSection, "SetThermalSysParams");
	m_workerPtr->m_logerPtr->m_INFO("m_setThermalSysParams = "+std::to_string(m_setThermalSysParams)+"\n" );

	const int Tempalarm = ini.readinteger(sSection, "Tempalarm", 0);                             //报警温度阈值，-100.0-1000.0度（精确到小数点后一位)
    const int Tempalert = ini.readinteger(sSection, "Tempalert", 0);                             //预警温度阈值，-100.0-1000.0度（精确到小数点后一位）


	if(mIP == "error" || mPort == 0 || mhckLibDir == "error"){
		m_workerPtr->m_logerPtr->m_ERROR("ini file load error\n");
		exit(-1);
	}

	m_bEnbaleThermometry = FALSE;
	m_bStreamOverlay = FALSE;
	m_bPictureOverlay = FALSE;
	m_bySensitivity = 0;

    m_comTemperatureColor = 1;
    m_iHighTemperature = 0;     //high valude   -273~10000
    m_iLowTemperature = 0;      //low value     -273~10000
    m_comDistanceUnit = 2;           // 距离单位: 0- 米(m)，1- 英尺(feet)，2-厘米（cm）  
    m_cmbFireImageModea = 0;
    m_cmbThermometryCurve = 0;
    m_fThernomertryEmissivity = 0.96;      //发射率(发射率 精确到小数点后两位)[0.01, 1.00](即：物体向外辐射能量的本领)
    m_byEnviroHumidity = 0;
    m_iEnviroTemperature = 0;
    m_iCorrectionVolume = 0;
    m_bChkCenterSpecialPoint = FALSE;
    m_bChkHighestSpecialPoint = FALSE;
    m_bChkLowestSpecialPoint = FALSE;
    m_bChkReflectiveEnabled = FALSE;
    m_dwDistanceMeter = 3;
    m_fReflectiveTemp = 0.0f;
    m_bShowTempStripEnable = FALSE;
    m_fAlarmVal = Tempalarm;                             //报警温度阈值，-100.0-1000.0度（精确到小数点后一位)
    m_fAlertVal = Tempalert;                             //预警温度阈值，-100.0-1000.0度（精确到小数点后一位）
    float   m_ThermalOpticalTransmittance = 1.0;  
    float   m_externalOpticsWindowCorrection = 20;   
    BOOL    m_displayMaxTemperatureEnabled = 1;             // 显示最高温 0-不显示 1-显示
    BOOL    m_displayMinTemperatureEnabled = 1;             // 显示最低温 0-不显示 1-显示
    BOOL    m_displayAverageTemperatureEnabled = 0;         // 显示平均温 0-不显示 1-显示
    BYTE    m_thermometryInfoDisplayposition    = 1;        // 测温信息显示位置 0-保留 1-跟随规则 2-屏幕左上角
    int		m_AlertFilteringTime = 0;
    int     m_AlarmFilteringTime = 0;
    BYTE    m_displayTemperatureInOpticalChannelEnabled = 0;
    BOOL    m_displayCentreTemperatureEnabled = FALSE;


}
ThermalCamera::~ThermalCamera(){
	closeHikSDK();
	if(_ImgBuff != NULL)
	{
		delete _ImgBuff;
		_ImgBuff = NULL;
	}
	m_workerPtr->m_logerPtr->m_INFO("hiksdk exited\n");
	m_workerPtr->m_logerPtr->m_INFO("~ThermalCamera() exited\n");
}




int ThermalCamera::mInitHikSDK()
{
    //device init
    NET_DVR_Init();
    mSDK_Version();
	//NET_DVR_SetLogToFile(3, "./sdkLog");

	printf("  \n");

	//如果调试过程碰到104预览组件加载失败错误，就需要在主程序中用 NET_DVR_SetSDKInitCfg 函数进行重新连接
	NET_DVR_LOCAL_SDK_PATH struComPath = {0};
	strcpy(struComPath.sPath, mhckLibDir.c_str());
	int res = NET_DVR_SetSDKInitCfg(NET_SDK_INIT_CFG_SDK_PATH, &struComPath);		//success on 1, false on 0
	printf("HCNetSDKCom path load success! sPath: %s -- %d\n",mhckLibDir.c_str(), res );

    //set connect and reconnect time
    NET_DVR_SetConnectTime(2000,1);    //waitTime, reconnect times
    NET_DVR_SetReconnect(10000, true);

    //register device, user login info
    NET_DVR_USER_LOGIN_INFO struLoginInfo = {0};
    struLoginInfo.bUseAsynLogin = false;
	char cameraInfo[200];
	snprintf (cameraInfo,200, "cameraIp: %s\n\tcameraPort: %d\n\tuserName: %s\n\tpassWord: %s\n",  
			mIP.c_str(), mPort, mUserName.c_str(),mPassword.c_str() );
	WorkerPtr->m_logerPtr->m_INFO(cameraInfo );

    struLoginInfo.wPort = mPort;
    strcpy(struLoginInfo.sDeviceAddress, mIP.c_str());
    strcpy(struLoginInfo.sUserName, mUserName.c_str());
    strcpy(struLoginInfo.sPassword, mPassword.c_str());

    //device info, output params
    _LUserID = NET_DVR_Login_V40(&struLoginInfo, &_StruDeviceInfoV40);
    if (_LUserID < 0)
    {
        printf("pyd1---Login error, error code: %d\n", NET_DVR_GetLastError());
        NET_DVR_Cleanup();
        return -1;
    }
    DwChannel = _StruDeviceInfoV40.struDeviceV30.byStartChan;

    //analog channels
    int analogChannels = _StruDeviceInfoV40.struDeviceV30.byChanNum;
    //ip channels
    int ipChannels = _StruDeviceInfoV40.struDeviceV30.byIPChanNum + _StruDeviceInfoV40.struDeviceV30.byHighDChanNum * 256;
    cout << "the max number of analog channels: " << analogChannels << endl;
    cout << "the max number of ip channels: " << ipChannels << endl;

  	int iRet;
	// //get 测温Mode配置
	if(mGetThermMode(_LUserID) == -1){
		const int ttt = 0;
	//debug
		//return -1;
	}

	//get 测温基本参数配置
	if(m_setThermalSysParams && setThermParams(_LUserID) == -1){
		return -1;
	}
	return 0;

#if 0
	// //get realtime params
	// NET_DVR_STD_CONFIG struStdConfig2 = { 0 };
	// NET_DVR_REALTIME_THERMOMETRY_COND struThermCond = { 0 };
	// struStdConfig2.lpCondBuffer = &DwChannel;
	// struStdConfig2.dwCondSize = sizeof(DwChannel);
	// struStdConfig2.lpInBuffer = NULL;
	// struStdConfig2.dwInSize = 0;
	
	// struStdConfig2.lpOutBuffer = &struThermCond;   //out param
	// struStdConfig2.dwOutSize = sizeof(struThermCond);

	// memset(m_szStatusBuf, 0, ISAPI_STATUS_LEN);
	// struStdConfig2.lpStatusBuffer = m_szStatusBuf;      //out param
	// struStdConfig2.dwStatusSize = ISAPI_STATUS_LEN;
	// //get TemplateModes
	// iRet = NET_DVR_GetSTDConfig(LUserID, NET_DVR_GET_REALTIME_THERMOMETRY, &struStdConfig2);
	// if (!iRet)	
	// {
	// 	printf("NET_DVR_GET_REALTIME_THERMOMETRY failed, error code: %d iRet: %d\n", NET_DVR_GetLastError(), iRet);
    //     return -1;
	// }
	// else
	// {
	// 	printf("NET_DVR_GET_REALTIME_THERMOMETRY success! iRet: %d\n", iRet);
	// 	printf ("NET_DVR_GET_REALTIME_THERMOMETRY:  %d\n", struThermCond.byMode);	//0 : normal
		
#endif
  
}

//using
int ThermalCamera::mHckRun_tcp()
{
    int res = mInitHikSDK();	//初始化sdk
	if (res == -1){
		WorkerPtr->m_logerPtr->m_ERROR("mhckRun error\n");
		return -1;
	}
	mDemo_GetDeviceState(_LUserID);
	if(mGetAbility_thermal(_LUserID) == -1){
		return -1;
	}

	if(mb_alarmDetect && mAlarmDetect_tcp(_LUserID) == -1)		//报警功能检测
	{
		return -1;
	}

	if(mb_realTempDetect && mRealTempDetect_tcp(_LUserID) == -1)		//realDetect 检测
	{
		return -1;
	}
	printf("********************\n");
	return 0;
}


//img char buff
BOOL CALLBACK MessageCallback3_imgCharBuff(LONG lCommand, NET_DVR_ALARMER *pAlarmer, char *pAlarmInfo, DWORD dwBufLen, void* pUser) 
{
	// NET_DVR_JPEGPARA strPicPara = {0};
	// strPicPara.wPicQuality = 0;	//图片质量系数：0-最好，1-较好，2-一般 
	// strPicPara.wPicSize = 500;	//500-384*288
	//printf("debug:  thermalcam.cpp::  MessageCallback3()\n");

	switch(lCommand)      
	{                
		case COMM_THERMOMETRY_ALARM: //温度预警或者温度报警         
		{
			//printf("温度预警或者温度报警 : \n");    
			NET_DVR_THERMOMETRY_ALARM struThermometryAlarm = {0};             
			memcpy(&struThermometryAlarm, pAlarmInfo, sizeof(NET_DVR_THERMOMETRY_ALARM));             
			if (0 == struThermometryAlarm.byRuleCalibType)             
			{                 
				printf("点测温: \n"); 
			}             
			else if (1 == struThermometryAlarm.byRuleCalibType || 2 == struThermometryAlarm.byRuleCalibType)             
			{
				char* imgChar = struThermometryAlarm.pThermalPicBuff;
				const int imgLen = struThermometryAlarm.dwThermalPicLen;
				const float fx = struThermometryAlarm.struHighestPoint.fX;
				const float fy = struThermometryAlarm.struHighestPoint.fY;
				const float maxTemp = struThermometryAlarm.fCurrTemperature;
				printf(">>> max temp: %f, imgBuff size: %d\n", maxTemp, imgLen);
		
				const string jsonStr = ThermalCamera::mCreateJson_alarm(imgLen, struThermometryAlarm.struHighestPoint.fX
																				, struThermometryAlarm.struHighestPoint.fY);
				
				const int buffSize = imgLen + jsonStr.size();
				
				#if 1    //new 一块内存, 图片的缓存
				memset(_ImgBuff, 0, _ImageBuffSize);
				memcpy(_ImgBuff, jsonStr.c_str(), jsonStr.size() );
				memcpy(_ImgBuff + jsonStr.size(), imgChar, imgLen);

				const int len = WorkerPtr->mSendBuff2Service(WorkerPtr->mConnfd, _ImgBuff, jsonStr.size() + imgLen);
				if(len == -1){
					printf("*** send info for service error\n");
				}	
				
				#else	//run sucess
				const string imgStr(imgChar, imgChar+imgLen);
				const string sendStr = jsonStr + imgStr;
				const int len = CLIENTTOSERVICE->m_sendStr2service(sendStr);
				
				if(len == -1){
					WARNING("send info for service error\n");
				}	
				writeFileIntoLocal(imgChar, imgLen, "/home/ljl/myprograms/thermal-hik/bin/img.jpg");
				#endif
			}
			printf("*** thermal alarm MessageCallback3_imgCharBuff problem\n");
			break;         
		} //case            
		case COMM_THERMOMETRY_DIFF_ALARM: //温差报警         
		{
			printf("温差报警 : \n");    
			NET_DVR_THERMOMETRY_DIFF_ALARM struThermometryDiffAlarm = {0};             
			memcpy(&struThermometryDiffAlarm, pAlarmInfo, sizeof(NET_DVR_THERMOMETRY_DIFF_ALARM));  
			if (0 == struThermometryDiffAlarm.byRuleCalibType)             
			{
				printf("点测温: \n");   
				      
			}             
			else if (1 == struThermometryDiffAlarm.byRuleCalibType || 2 == struThermometryDiffAlarm.byRuleCalibType)             
			{
				printf("线测温或者框测温 : \n");          
				int i = 0;                 
				int iPointNum = struThermometryDiffAlarm.struRegion[0].dwPointNum;                 
				for (i = 0; i < iPointNum; i++)                 
				{                     
					float fX = struThermometryDiffAlarm.struRegion[0].struPos[i].fX;                     
					float fY = struThermometryDiffAlarm.struRegion[0].struPos[i].fY;                     
					printf("测温区域1坐标点: X%d:%f,Y%d:%f;\n", iPointNum + 1, fX, iPointNum + 1, fY);                 
				}                 
				iPointNum = struThermometryDiffAlarm.struRegion[1].dwPointNum;                 
				for (i = 0; i < iPointNum; i++)                 
				{                     
					float fX = struThermometryDiffAlarm.struRegion[1].struPos[i].fX;                     
					float fY = struThermometryDiffAlarm.struRegion[1].struPos[i].fY;                     
					printf("测温区域2坐标点: X%d:%f,Y%d:%f;\n", iPointNum + 1, fX, iPointNum + 1, fY);                 
				}          
			}

			break;         
		}             
		default:
		{          
			printf("其他报警，报警信息类型: %d\n", lCommand);             
			break;
		}  
	}//switch   
	return TRUE; 
}

// //send imgBuff to service
int ThermalCamera::mAlarmDetect_tcp(const int lUserId)
{
 	//set alarm callback function
 	//设置报警回调函数     
    NET_DVR_SetDVRMessageCallBack_V31(MessageCallback3_imgCharBuff, NULL);
    //启用布防     
    NET_DVR_SETUPALARM_PARAM  struAlarmParam={0};     
    struAlarmParam.dwSize=sizeof(struAlarmParam);     
    //温度或者温差报警不需要设置其他报警布防参数，不支持      
    mLHandle_alarm = NET_DVR_SetupAlarmChan_V41(lUserId, & struAlarmParam);     
    if (mLHandle_alarm < 0)     {         
        printf("NET_DVR_SetupAlarmChan_V41 error, %d\n", NET_DVR_GetLastError());           
        return -1;     
    }
	else{
		printf("\033[1;32mNET_DVR_SetupAlarmChan_V41 success, %d\033[0m\n", mLHandle_alarm);    
	}
	return 0;
}



//real temp info and send img
void CALLBACK GetThermInfoCallback_tcp(DWORD dwType, void* lpBuffer, DWORD dwBufLen, void* pUserData) 
{  
	if (dwType == NET_SDK_CALLBACK_TYPE_DATA)     
	{         
		LPNET_DVR_THERMOMETRY_UPLOAD lpThermometry = new NET_DVR_THERMOMETRY_UPLOAD;         
		memcpy(lpThermometry, lpBuffer, sizeof(*lpThermometry));

		if(lpThermometry->byRuleCalibType == 0) //点测温         
		{             
			printf("点测温信息:fTemperature[%f]\n", lpThermometry->struPointThermCfg.fTemperature);  
			printf("debug:  thermalcam.cpp::  isCapPicture ###4\n");
		}

		if((lpThermometry->byRuleCalibType==1)||(lpThermometry->byRuleCalibType==2)) //框/线测温         
		{
			SendTempImgcond++;
			SendTempImgcond %= 1000;
			
			if(SendTempImgcond % SendTempImgInterval == 0){
				if(IsSendRealThermalImg){	//send json-img
					const string imgPath = AlarmPath_local + "/" + getImageName(".jpg");
					if ( ThermalCamera::mCapPicture(_LUserID, DwChannel, imgPath) == 0){
						ifstream is(imgPath.c_str(), ifstream::in | ios::binary);
						is.seekg(0, is.end);
						const int imgLen = is.tellg();
						is.seekg(0, is.beg);

						char imgBuff[imgLen];
						is.read(imgBuff, imgLen);
						is.close();

						deleteFile(imgPath);

						const string jsonStr = ThermalCamera::mCreateJson_deviceInfo(lpThermometry->struLinePolygonThermCfg.fMaxTemperature, 
																				lpThermometry->struLinePolygonThermCfg.fMinTemperature, 
																				lpThermometry->struLinePolygonThermCfg.fAverageTemperature, 
																				lpThermometry->struLinePolygonThermCfg.fTemperatureDiff
																				, 0
																				, UtilsTools::mgetLocalTime_YMDHMS(), imgLen);
						const int jsonStr_len = jsonStr.size();
				
						char sendBuff[jsonStr_len + imgLen];
						memset(sendBuff, 0, jsonStr_len + imgLen);
						memcpy(sendBuff, jsonStr.c_str(), jsonStr_len);
						memcpy(sendBuff + jsonStr_len, imgBuff, imgLen);
						const int len = WorkerPtr->mSendBuff2Service(WorkerPtr->mConnfd, sendBuff, jsonStr_len + imgLen);
						if(len == -1){
							printf("warning: send info for service error\n");
						}	
						else{
							printf(">>> real thermal info: %s\n", jsonStr.c_str());
						}
					}
					else{
						printf("warning: capPicure error\n");
					}

				}
				else{	//send json
					//printf("debug thermalcam.cpp********%d******max temp: %f\n",SendTempImgInterval, lpThermometry->struLinePolygonThermCfg.fMaxTemperature);
					const std::string jsonStr = ThermalCamera::mCreateJson_deviceInfo(
																lpThermometry->struLinePolygonThermCfg.fMaxTemperature, 
																lpThermometry->struLinePolygonThermCfg.fMinTemperature, 
																lpThermometry->struLinePolygonThermCfg.fAverageTemperature, 
																lpThermometry->struLinePolygonThermCfg.fTemperatureDiff
																, 0
																, UtilsTools::mgetLocalTime_YMDHMS(), 0);
			
					const int len = WorkerPtr->mSendStr2service(WorkerPtr->mConnfd, jsonStr);
					if(len == -1){
						printf("warning: send info for service error\n");
					}	
					else{
						printf(">>> real thermal info: %s\n", jsonStr.c_str());
					}
				}//else
			}//if
  
		}  //if             
		if (lpThermometry != NULL)         
		{             
			delete lpThermometry;             
			lpThermometry = NULL;         
		}     

	}   //if
	else if (dwType == NET_SDK_CALLBACK_TYPE_STATUS)     
	{    

		DWORD dwStatus = *(DWORD*)lpBuffer;         
		if (dwStatus == NET_SDK_CALLBACK_STATUS_SUCCESS)         
		{             
			printf("dwStatus:NET_SDK_CALLBACK_STATUS_SUCCESS\n");                     
		}         
		else if (dwStatus == NET_SDK_CALLBACK_STATUS_FAILED)         
		{             
			DWORD dwErrCode = *(DWORD*)((char *)lpBuffer + 4);             
			printf("NET_DVR_GET_MANUALTHERM_INFO failed, Error code %d\n", dwErrCode);         
		}     
	} 

} 

int ThermalCamera::mRealTempDetect_tcp(const int lUserId)
{
	//启动实时温度检测
	NET_DVR_REALTIME_THERMOMETRY_COND struThermCond = { 0 };
	struThermCond.dwSize = sizeof(struThermCond);
	struThermCond.byRuleID = m_rule;       //规则ID，0代表获取全部规则，具体规则ID从1开始
	struThermCond.dwChan = DwChannel; 	  //从1开始，0xffffffff代表获取全部通道
	struThermCond.byMode = 1;			//长连接模式：0- 保留（兼容不支持该功能的老设备），1- 定时模式，2-  温差模式
	struThermCond.wInterval = m_realtemp_interval;		//send /2s  only work for 温差模式

	/*
	1-定时模式：设备每隔一秒上传各个规则测温数据的最高温、最低温和平均温度值、温差。
	2-温差模式：若上一秒与下一秒的最高温或者最低温或者平均温或者温差值的温差大于等于2摄氏度，
				则上传最高温、最低温和平均温度值；若大于等于一个小时温差值均小于2摄氏度，则上传最高温、最低温、平均温和温差值  
	*/
	mLHandle_realtemp = NET_DVR_StartRemoteConfig(lUserId, NET_DVR_GET_REALTIME_THERMOMETRY, 
												&struThermCond, sizeof(struThermCond), 
												GetThermInfoCallback_tcp, this);
	if (mLHandle_realtemp < 0)
	{
		printf("NET_DVR_GET_REALTIME_THERMOMETRY failed, error code: %d lHandle: %d\n", NET_DVR_GetLastError(), mLHandle_realtemp);
		return -1;
	}
	else
	{
		printf("\033[1;32mNET_DVR_GET_REALTIME_THERMOMETRY success! lHandle: %d\033[0m\n", mLHandle_realtemp);
	}
    sleep(1);
	return 0;
}

void ThermalCamera::closeHikSDK()
{
	// //关闭长连接配置接口所创建的句柄，释放资源  LHandle_alarm
	if ( closeRealTempDetect(mLHandle_realtemp) == 0){
		printf("撤销 realDetect 通道 success\n");
	}
	else{
		printf("撤销 realDetect 通道 failed\n");
	}

	//撤销布防上传通道
	if ( closeAlarmDetect(mLHandle_alarm) == 0){
		printf("撤销布防上传通道 success\n");
	}
	else{
		printf("撤销布防上传通道 failed\n");
	}
	
  	//注销用户
	NET_DVR_Logout(_LUserID);
	//释放SDK资源
	NET_DVR_Cleanup();
	printf("Thermal camera closed! Time: %ld\n", time(NULL)); //和初始化时秒数相减，可以查看运行秒数
}

int ThermalCamera::closeRealTempDetect(const int lHandle_realtemp)
{
	//关闭长连接配置接口所创建的句柄，释放资源  LHandle_alarm
	if (lHandle_realtemp != -1 && !NET_DVR_StopRemoteConfig(lHandle_realtemp))
	{
		printf("NET_DVR_StopRemoteConfig failed, error code: %d\n", NET_DVR_GetLastError());
		return -1;
	}
	return 0;
}
int ThermalCamera::closeAlarmDetect(const int lHandle_alarm)
{
	//撤销布防上传通道
	if(lHandle_alarm == -1 ){
		printf("LHandle_alarm == -1\n");
	}
	else if (!NET_DVR_CloseAlarmChan_V30(lHandle_alarm)){
		printf("NET_DVR_CloseAlarmChan_V30 failed, error, %d\n", NET_DVR_GetLastError());
		return -1;
	}
	return 0;
}

void ThermalCamera::mSDK_Version()
{
    unsigned int uiVersion = NET_DVR_GetSDKBuildVersion();

    char strTemp[1024] = {0};
    sprintf(strTemp, "HCNetSDK V%d.%d.%d.%d\n", \
        (0xff000000 & uiVersion)>>24, \
        (0x00ff0000 & uiVersion)>>16, \
        (0x0000ff00 & uiVersion)>>8, \
        (0x000000ff & uiVersion));
    printf("%s", strTemp);
}


/*
* Get device state 设备工作状态信息结构体。
Members
    dwDeviceStatic  设备的状态：0－正常；1－CPU占用率太高，超过85%；2－硬件错误，例如串口异常  
    struHardDiskStatic  硬盘状态  
    struChanStatic  通道状态  
    byAlarmInStatic  报警输入口的状态：0-没有报警；1-有报警  
    byAlarmOutStatic  报警输出口的状态：0-没有输出，1-有报警输出  
    dwLocalDisplay  本地显示状态：0-正常，1-不正常  
    byAudioChanStatus  表示语音通道的状态：0-未使用，1-使用中，0xff无效  
    byRes  保留，置为0 
*/
int ThermalCamera::mDemo_GetDeviceState(LONG lUserID)
{
    printf("设备工作状态信息:\n");
    NET_DVR_WORKSTATE_V30    struWorkState;
    if (NET_DVR_GetDVRWorkState_V30(lUserID, &struWorkState))
    {
        printf("pyd---NET_DVR_GetDVRWorkState_V30 success.\n");
    } 
    else
    {
        printf("pyd---NET_DVR_GetDVRWorkState_V30 error, %d.\n", NET_DVR_GetLastError());
        return HPR_ERROR;
    }

    printf("  设备的状态：0－正常；1－CPU占用率太高, 2－硬件错误，例如串口异常 -> %d\n", struWorkState.dwDeviceStatic);
    //printf("硬盘状态:%d\n", struWorkState.struHardDiskStatic);
    //printf("通道状态:%d\n", struWorkState.struChanStatic);
    printf("  报警输入口的状态：0-没有报警；1-有报警 -> %d\n", *struWorkState.byAlarmInStatic);
    printf("  报警输出口的状态：0-没有输出，1-有报警输出 -> %d\n", *struWorkState.byAlarmOutStatic);
    printf("  本地显示状态：0-正常，1-不正常 -> %d\n", struWorkState.dwLocalDisplay);
    printf("  语音通道的状态：0-未使用，1-使用中，0xff无效 -> %d\n", *struWorkState.byAudioChanStatus);
    return HPR_OK;
}



/**
 * @brief transform " " of time into "_"
 * @param const string imgType, eg. ".jpg"
*/
string getImageName(const string imgType)
{
	std::string localTime = UtilsTools::mgetLocalTime_YMDHMS();
	const int idx = localTime.find(" ");
	const int len = localTime.size();
	localTime = localTime.substr(0,idx) + "_" + localTime.substr(idx+1, len-1-idx) + imgType.c_str();
	return localTime;
}

int ThermalCamera::mGetThermMode(const int lUserID)
{
	//get 测温Mode配置
    NET_DVR_STD_CONFIG struStdConfig = { 0 };

	NET_DVR_THERMOMETRY_MODE struThermMode = { 0 };
    struStdConfig.lpCondBuffer = &DwChannel;
	struStdConfig.dwCondSize = sizeof(DwChannel);
	struStdConfig.lpInBuffer = NULL;
	struStdConfig.dwInSize = 0;
	
	struStdConfig.lpOutBuffer = &struThermMode;   //out param
	struStdConfig.dwOutSize = sizeof(struThermMode);

	char  szStatusBuf[ISAPI_STATUS_LEN];
	memset(szStatusBuf, 0, ISAPI_STATUS_LEN);
	struStdConfig.lpStatusBuffer = szStatusBuf;      //out param
    struStdConfig.dwStatusSize = ISAPI_STATUS_LEN;
	//get TemplateModes
	int iRet = NET_DVR_GetSTDConfig(lUserID, NET_DVR_GET_THERMOMETRY_MODE, &struStdConfig);
	if (!iRet)	
	{
		printf("NET_DVR_GET_THERMOMETRY_MODE failed, error code: %d iRet: %d\n", NET_DVR_GetLastError(), iRet);
        return -1;
	}
	else
	{
		printf("NET_DVR_GET_THERMOMETRY_MODE success! iRet: %d  ", iRet);
		printf ("MODE:  %d, 0 : normal\n", struThermMode.byMode);	//0 : normal
		
	}
	return 0;
}

int ThermalCamera::setThermParams(const int lUserID)
{
	printf("setParams: \n");
	int iRet;

	//set system params
	iRet = setThermParams_sys(lUserID);
	if(iRet == -1){
		return -1;
	}
	iRet = setThermParams_basicParam(lUserID);
	if(iRet == -1){
		printf("setThermParams_basicParam() error\n");
		// return -1;
	}

	return 0;
}

//strucPiccFG.byOSDType = 0   year-month-day          //0-8
int ThermalCamera::setThermParams_sys(const int lUserID){
	//get system params
	DWORD len;	//out param
	NET_DVR_PICCFG_V40 strucPiccFG = { 0 };		// out param
	int iRet = NET_DVR_GetDVRConfig(lUserID, NET_DVR_GET_PICCFG_V40, DwChannel, &strucPiccFG, sizeof(strucPiccFG), &len);
	if (!iRet)
	{
		printf("	NET_DVR_GET_PICCFG_V40 failed, error code: %d iRet: %d\n", NET_DVR_GetLastError(), iRet);
        return -1;
	}
	else
	{
		printf("	NET_DVR_GET_PICCFG_V40 success! iRet: %d\n", iRet);
	}
	//set system params
	const string robotName = m_selfName;
	strncpy((char*)strucPiccFG.sChanName, robotName.c_str(), robotName.length()+1 );
	strucPiccFG.byOSDType = m_byOSDType;			//year-month-day
	strucPiccFG.byDispWeek = m_byDispWeek;
	
	iRet = NET_DVR_SetDVRConfig(lUserID, NET_DVR_SET_PICCFG_V40, DwChannel, &strucPiccFG, sizeof(strucPiccFG));
	if (!iRet)
	{
		printf("	NET_DVR_SET_PICCFG_V40 failed, error code: %d iRet: %d\n", NET_DVR_GetLastError(), iRet);
        return -1;
	}
	else
	{
		printf("	NET_DVR_SET_PICCFG_V40 success! iRet: %d\n", iRet);
		printf("	strucPiccFG.sChanName: %s\n", strucPiccFG.sChanName);
		printf("	strucPiccFG.dwShowOsd: %d\n", strucPiccFG.dwShowOsd);
		printf("	strucPiccFG.byOSDType: %d\n", strucPiccFG.byOSDType);
		printf("	strucPiccFG.byDispWeek: %d\n", strucPiccFG.byDispWeek);
	}
	printf("	***\n");
	printf("	image param set success\n");
	printf("	***\n");
	//<<<
	return 0;
}

int ThermalCamera::setThermParams_basicParam(const int lUserID)
{
	NET_DVR_STD_CONFIG struStdConfig = { 0 };
	char  szStatusBuf[ISAPI_STATUS_LEN];
	//get 测温基本参数配置
	NET_DVR_THERMOMETRY_BASICPARAM struThermometryBasic = { 0 };
    struStdConfig.lpCondBuffer = &DwChannel;
	struStdConfig.dwCondSize = sizeof(DwChannel);
	struStdConfig.lpInBuffer = NULL;
	struStdConfig.dwInSize = 0;
	
	struStdConfig.lpOutBuffer = &struThermometryBasic;   //out param
	struStdConfig.dwOutSize = sizeof(struThermometryBasic);

	memset(szStatusBuf, 0, ISAPI_STATUS_LEN);
	struStdConfig.lpStatusBuffer = szStatusBuf;      //out param
    struStdConfig.dwStatusSize = ISAPI_STATUS_LEN;
	int iRet = NET_DVR_GetSTDConfig(lUserID, NET_DVR_GET_THERMOMETRY_BASICPARAM, &struStdConfig);
	if (!iRet)	
	{
		printf("	NET_DVR_GET_THERMOMETRY_BASICPARAM failed, error code: %d iRet: %d\n", NET_DVR_GetLastError(), iRet);
        return -1;
	}
	else
	{
		printf("	NET_DVR_GET_THERMOMETRY_BASICPARAM success! iRet: %d\n", iRet);
	}
	//set 测温基本参数配置
	{

    // struThermometryBasic.byEnabled = m_bEnbaleThermometry;
    // struThermometryBasic.byStreamOverlay = m_bStreamOverlay;
    // struThermometryBasic.byPictureOverlay = m_bPictureOverlay;
    // struThermometryBasic.byThermometryRange = 1; //测温范围（这里以摄氏度为单位计算，其他单位由上层自行转换）：0- 默认值，1- (-20~150)，2- (0~550)  0xff :auto
	// struThermometryBasic.byemissivityMode = 0xff; //发射率配置类型： 1- 粗糙(0.95)，2- 较粗糙(0.80)，3- 较光滑(0.60)，4- 光滑(0.30)，0xff-  自定义(0.01-1.00)  
	// struThermometryBasic.byThermometryUnit = m_byThermometryUnit;  //测温单位（所有测温配置功能中温度参数对应的单位）: 0- 摄氏度（℃），1- 华氏度（℉），2- 开尔文(K) 
    // struThermometryBasic.struTempColor.byType = m_comTemperatureColor;
    // struThermometryBasic.struTempColor.iHighTemperature = m_iHighTemperature;
    // struThermometryBasic.struTempColor.iLowTemperature = m_iLowTemperature;
    
    // struThermometryBasic.byFireImageModea = m_cmbFireImageModea;
    // struThermometryBasic.byThermometryCurve = m_cmbThermometryCurve;
    // struThermometryBasic.fEmissivity = m_fThernomertryEmissivity;		//发射率(发射率 精确到小数点后两位)[0.01, 1.00](即：物体向外辐射能量的本领)
	// struThermometryBasic.byDistanceUnit = m_comDistanceUnit;					//距离单位: 0- 米(m)，1- 英尺(feet)，2-厘米（cm） 
    // struThermometryBasic.byEnviroHumidity = m_byEnviroHumidity;
    // struThermometryBasic.iEnviroTemperature = m_iEnviroTemperature;		//-273~10000 
    // struThermometryBasic.iCorrectionVolume = m_iCorrectionVolume;
    // struThermometryBasic.bySpecialPointThermType = 0;
    // struThermometryBasic.bySpecialPointThermType |= (m_bChkCenterSpecialPoint << 0);
    // struThermometryBasic.bySpecialPointThermType |= (m_bChkHighestSpecialPoint << 1);
    // struThermometryBasic.bySpecialPointThermType |= (m_bChkLowestSpecialPoint << 2);
    // struThermometryBasic.byReflectiveEnabled = m_bChkReflectiveEnabled;
    // struThermometryBasic.wDistance = m_dwDistanceMeter;
    // struThermometryBasic.fReflectiveTemperature = m_fReflectiveTemp;
    // struThermometryBasic.byShowTempStripEnable = m_bShowTempStripEnable;		//显示温度条使能：0- 否，1- 是 

     struThermometryBasic.fAlert = m_fAlertVal;			//***
     struThermometryBasic.fAlarm = m_fAlarmVal;			//***
    // struThermometryBasic.fThermalOpticalTransmittance = m_ThermalOpticalTransmittance;
    // struThermometryBasic.fExternalOpticsWindowCorrection = m_externalOpticsWindowCorrection;
    // struThermometryBasic.byDisplayMaxTemperatureEnabled = m_displayMaxTemperatureEnabled;
    // struThermometryBasic.byDisplayMinTemperatureEnabled = m_displayMinTemperatureEnabled;
    // struThermometryBasic.byDisplayAverageTemperatureEnabled = m_displayAverageTemperatureEnabled;
    // struThermometryBasic.byThermometryInfoDisplayposition = m_thermometryInfoDisplayposition;
    // struThermometryBasic.dwAlertFilteringTime = m_AlertFilteringTime;
    // struThermometryBasic.dwAlarmFilteringTime = m_AlarmFilteringTime;
    // struThermometryBasic.bydisplayTemperatureInOpticalChannelEnabled=m_displayTemperatureInOpticalChannelEnabled;
    // struThermometryBasic.byDisplayCentreTemperatureEnabled = m_displayCentreTemperatureEnabled;
    // struThermometryBasic.dwSize = sizeof(struThermometryBasic);
	}

    struStdConfig.lpCondBuffer = &DwChannel;
    struStdConfig.dwCondSize = sizeof(DwChannel);
    struStdConfig.lpInBuffer = &struThermometryBasic;
    struStdConfig.dwInSize = sizeof(struThermometryBasic);
    memset(szStatusBuf, 0, ISAPI_STATUS_LEN);
    struStdConfig.lpStatusBuffer = szStatusBuf;
    struStdConfig.dwStatusSize = ISAPI_STATUS_LEN;
    
    iRet = NET_DVR_SetSTDConfig(lUserID, NET_DVR_SET_THERMOMETRY_BASICPARAM, &struStdConfig);
    if (!iRet)	
	{

		printf("	NET_DVR_SET_THERMOMETRY_BASICPARAM failed, error code: %d iRet: %d\n", NET_DVR_GetLastError(), iRet);
        return -1;
	}
	else
	{	
		printf("	NET_DVR_SET_THERMOMETRY_BASICPARAM success! iRet: %d\n", iRet);
	}

	//get params that have been setted
	NET_DVR_THERMOMETRY_BASICPARAM struThermometryBasicCheckout = { 0 };
    struStdConfig.lpCondBuffer = &DwChannel;
	struStdConfig.dwCondSize = sizeof(DwChannel);
	struStdConfig.lpInBuffer = NULL;
	struStdConfig.dwInSize = 0;
	
	struStdConfig.lpOutBuffer = &struThermometryBasicCheckout;   //out param
	struStdConfig.dwOutSize = sizeof(struThermometryBasicCheckout);

	memset(szStatusBuf, 0, ISAPI_STATUS_LEN);
	struStdConfig.lpStatusBuffer = szStatusBuf;      //out param
    struStdConfig.dwStatusSize = ISAPI_STATUS_LEN;
	iRet = NET_DVR_GetSTDConfig(lUserID, NET_DVR_GET_THERMOMETRY_BASICPARAM, &struStdConfig);
	if (!iRet)	
	{
		printf("	NET_DVR_GET_THERMOMETRY_BASICPARAM failed, error code: %d iRet: %d\n", NET_DVR_GetLastError(), iRet);
        return -1;
	}
	else
	{
		printf("	NET_DVR_GET_THERMOMETRY_BASICPARAM success! iRet: %d\n", iRet);
		printf("	thermal camera alarm template: %.2f\n", struThermometryBasicCheckout.fAlarm);
		printf("	thermal camera alert template: %.2f\n", struThermometryBasicCheckout.fAlert);
		
	}
	return 0;
}

/**
 * @brief 获取相机能力集
*/
int ThermalCamera::mGetAbility_thermal(const int lUserID)
{
	NET_DVR_STD_ABILITY struStdAbility = {0};
	char  outBuf[ISAPI_OUT_LEN];
	memset(outBuf, 0, ISAPI_OUT_LEN);

	char  statusBuf[ISAPI_STATUS_LEN];
	memset(statusBuf, 0, ISAPI_STATUS_LEN);

    struStdAbility.lpCondBuffer = &DwChannel;
	struStdAbility.dwCondSize = sizeof(DwChannel);
	
	struStdAbility.lpOutBuffer = outBuf;   //out param
	struStdAbility.dwOutSize = ISAPI_OUT_LEN;

	struStdAbility.lpStatusBuffer = statusBuf;      //out param
    struStdAbility.dwStatusSize = ISAPI_STATUS_LEN;
	//get abilities
	printf("thermal abilies: \n");
	int iRet = NET_DVR_GetSTDAbility(lUserID, NET_DVR_GET_THERMAL_CAPABILITIES, &struStdAbility);
	if (!iRet)	
	{
		printf("	NET_DVR_GET_THERMAL_CAPABILITIES, error code: %d iRet: %d\n", NET_DVR_GetLastError(), iRet);
        return -1;
	}
	else
	{
		printf("	NET_DVR_GET_THERMAL_CAPABILITIES success! iRet: %d  \n", iRet);
	}

	iRet = NET_DVR_GetSTDAbility(lUserID, NET_DVR_GET_TEMP_HUMI_CAPABILITIES, &struStdAbility);
	if (!iRet)	
	{
		printf("	NET_DVR_GET_TEMP_HUMI_CAPABILITIES, error code: %d iRet: %d\n", NET_DVR_GetLastError(), iRet);
        return -1;
	}
	else
	{
		printf("	NET_DVR_GET_TEMP_HUMI_CAPABILITIES success! iRet: %d  \n", iRet);
	}
	return 0;
}


void deleteFile(const string filePath)
{
	if(access(filePath.c_str(), F_OK) == 0){
		const string rmImg = "rm " + filePath;
		system(rmImg.c_str());
	}
}

int ThermalCamera::mCapPicture(const int inLUserID, const int channel, std::string inOutPicturePath)
{
    int iRet;
    NET_DVR_JPEGPARA strPicPara = {0};
    //strPicPara.wPicQuality = 2;
    //strPicPara.wPicSize = 0;
    strPicPara.wPicQuality = 0;	//图片质量系数：0-最好，1-较好，2-一般 
	strPicPara.wPicSize = 500;	//500-384*288
   
    iRet = NET_DVR_CaptureJPEGPicture(inLUserID, channel, &strPicPara, (char*)inOutPicturePath.c_str());
    if (!iRet)
    {
        printf("pyd1---NET_DVR_CaptureJPEGPicture error, %d\n", NET_DVR_GetLastError());
        return -1;       //-1
    }


    return 0;
}




std::string ThermalCamera::mCreateJson_alarm(const int imgBuffSize, const float fx, const float fy)
{
    std::string strjson;
    Json::Value root, workInfo;
    Json::StreamWriterBuilder writeBuild;
    std::ostringstream os;

	if(WorkerPtr == NULL)
	{
		printf("error: WorkerPtr == NULL");
		exit(-1);
	}
	workInfo = WorkerPtr->m_workInfoInit();
    root["ImgBuffSize"] = imgBuffSize;
    root["DetectCommand"]["Command"] = "UpdatePic";
    root["DetectCommand"]["Args"]["ImageProcessMode"] = "TempAlarm";
    root["DetectCommand"]["Args"]["Positions"] = 0;
    root["DetectCommand"]["Args"]["File_Path"] = "imgPath"; //"/home/ljl/catkin_tcp/socket_part/test/900005.png";     //linux service addr
    root["DetectCommand"]["Args"]["Time"] = UtilsTools::mgetLocalTime_YMDHMS();
    root["DetectCommand"]["Args"]["Task_ID"] = "";
    root["DetectCommand"]["Args"]["fx"] = to_string(fx);
    root["DetectCommand"]["Args"]["fy"] = to_string(fy); 

	workInfo["data"] = root;

    std::unique_ptr<Json::StreamWriter> jsonWriter(writeBuild.newStreamWriter());
    jsonWriter->write(workInfo,&os);
    strjson = "*****" + os.str() + "#####";
    return strjson;
}

std::string ThermalCamera::mCreateJson_deviceInfo(const float max, const float min, const float ave, const float diff, const int pos, const string time
                                                    , const int imgSize)
{
    std::string jsonStr;
    Json::Value  TunnelTemperature , root;
    Json::StreamWriterBuilder writerBuilder;
    std::ostringstream os;

    TunnelTemperature["ID"] = WorkerPtr->mId;
    TunnelTemperature["Maximum"] = max;
    TunnelTemperature["Minimal"] = min;
    TunnelTemperature["Average"] = ave;
    TunnelTemperature["Diff"] = ave;
    TunnelTemperature["CurrentPosition"] = pos;
    TunnelTemperature["CurrentTime"] = time;

    root["TunnelTemperature"] = Json::Value(TunnelTemperature);

    if(imgSize>0){
        root["ImgBuffSize"] = imgSize;
    }

	std::unique_ptr<Json::StreamWriter> jsonWrite(writerBuilder.newStreamWriter() );
	if(jsonWrite->write(root, &os) != 0) return "null";
	jsonStr = os.str();

	
    return "*****" + jsonStr + "#####";
}




//#############################################################   ftp 传输
#if 0
int thermal::mhckRun_ftp()
{
    int res = initHikSDK();	//初始化sdk
	if (res == -1){
		printf("mhckRun error\n");
		return -1;
	}
	mDemo_GetDeviceState(LUserID);
	if(mGetAbility_thermal(LUserID) == -1){
		return -1;
	}
	if(mb_alarmDetect && AlarmDetect(LUserID) == -1)		//报警功能检测
	{
		return -1;
	}
	if(mb_realTempDetect && RealTempDetect(LUserID) == -1)		//realDetect 检测
	{
		return -1;
	}
	// if(mRealTempDetect_tcp(LUserID) == -1)		//realDetect 检测
	// {
	// 	return -1;
	// }
	printf("********************\n");
	return 0;
}


// //设置报警回调函数  
// int thermal::AlarmDetect(const int lUserId)
// {
//  	//set alarm callback function
//  	//设置报警回调函数     
//     NET_DVR_SetDVRMessageCallBack_V31(MessageCallback_localImg, NULL);
//     //启用布防     
//     NET_DVR_SETUPALARM_PARAM  struAlarmParam={0};     
//     struAlarmParam.dwSize=sizeof(struAlarmParam);     
//     //温度或者温差报警不需要设置其他报警布防参数，不支持      
//     mLHandle_alarm = NET_DVR_SetupAlarmChan_V41(lUserId, & struAlarmParam);     
//     if (mLHandle_alarm < 0)     {         
//         printf("NET_DVR_SetupAlarmChan_V41 error, %d\n", NET_DVR_GetLastError());           
//         return -1;     
//     }
// 	else{
// 		printf("\033[1;32mNET_DVR_SetupAlarmChan_V41 success, %d\033[0m\n", mLHandle_alarm);    
// 	}
// 	return 0;
// }

// string regularCapPictureAndFtpSend(const int lUserId, const int channel, const string localSaveImg_tempPath, const string ftpImagePath)
// {
// 	//printf("线测温或者框测温: \n");
// 	const string imgName = getImageName(".jpg");  
// 	const string filePathName = localSaveImg_tempPath + "/" + imgName;	//save local
// 	//const string data = getcurrentDate();

// 	capPicture(lUserId, channel, filePathName.c_str());
// 	sendftp(IP_service, filePathName, ftpImagePath, "robot001", "robot001", "./thermal_normal.sh");

// 	return ftpImagePath + "/" + imgName;
// }


// void writeFileIntoLocal(char *pfile, const unsigned int len, const string path)
// {
// 	FILE *fp = NULL;
// 	fp = fopen(const_cast<char*>(path.c_str() ), "wb");
// 	fwrite(pfile, len, 1, fp);
// 	fclose(fp);
// }



// void pushAlarm(const string &strImgPath, const string &strImg, const float point_x, const float point_y)
// {
// 	std::unique_lock<std::mutex> lock(mutexTempAlarm);		//automatically calls lock on mtx
// 	isTempAlarm = true;
// 	//strncpy(TempAlarmImagePath, strImgPath.c_str(), strImgPath.length() + 1); // 注意，一定要加1，否则没有赋值'\0'
// 	TempAlarmImagePath = strImgPath;
// 	highPositionFx = point_x;
// 	highPositionFy = point_y;
// 	//alarmImage = matImg.clone();
// }
// void setThermalTempInfo(const float max, const float min, const float avg, const float diff, const string ftpSendImgPath)
// {
// 	std::unique_lock<std::mutex> lock(mutexTempInfo);
// 	max_thermalTemp = max;
// 	min_thermalTemp = min;
// 	avg_thermalTemp = avg;
// 	diff_thermalTemp = diff;

// 	isCapPicture = true;
// 	thermalImagePath_ftp = ftpSendImgPath;
// }
// void getThermalTempInfo(float &max, float &min, float &avg, float &diff, string &ftpSendImgPath)
// {
// 	std::unique_lock<std::mutex> lock(mutexTempInfo);
// 	max = max_thermalTemp;
// 	min = min_thermalTemp;
// 	avg = avg_thermalTemp;
// 	diff = diff_thermalTemp;

// 	isCapPicture = false;
// 	ftpSendImgPath = thermalImagePath_ftp;
// }

// //imgpath:  src source
// int sendftp(const string FTPServer, const string imgpath, const string uploadDirectory, const string ftpUser, const string ftopassword, const string shName)
// {       

//     char FTPPort[20] = "21";
// 	string ShScript = shName;				//"./thermal_normal.sh" ;
// 	FILE *file = fopen(ShScript.c_str(), "w");
// 	if (file)
// 	{
// 	// 参数说明详见第一部分
// 		fprintf(file, "#!/bin/bash\n"				
// 			"ncftpput " "-u %s " "-p %s " "-P %s " " %s " 
// 			" %s %s >/dev/null 2&>/dev/null\n"
// 			"path=%s\n"
// 			// "if [ -f \"$path\" ];then\n"
// 			// "	sleep 0.1"
// 			// "	rm $path\n"
// 			// "fi\n"
// 			"!\n"
// 			"exit",
// 			// 前后加！的作用类似C中的{}，此处的作用是禁止交互和表面shell回显信息
// 			ftpUser.c_str(), ftopassword.c_str(), FTPPort, FTPServer.c_str(), 
// 			uploadDirectory.c_str(), imgpath.c_str(), imgpath.c_str()
// 			);
// 		fclose(file);
// 		chmod(ShScript.c_str(), 0755);
// 		//ShScript += "&";
// 		// 通过system函数执行脚本
// 		system(ShScript.c_str());

// 		if(access(imgpath.c_str(), F_OK) == 0){
// 			const string rmImg = "rm " + imgpath;
// 			system(rmImg.c_str());
// 		}
// 	}
// 	else
// 	{
// 		printf("[Error] create shell script .bat:  %s failed!\n", ShScript.c_str());
// 		return -1;
// 	}
// 	return 0;
// }



// int thermal::RealTempDetect(const int lUserId)
// {
// 	//启动实时温度检测
// 	NET_DVR_REALTIME_THERMOMETRY_COND struThermCond = { 0 };

// 	struThermCond.dwSize = sizeof(struThermCond);
// 	struThermCond.byRuleID = m_rule;       //规则ID，0代表获取全部规则，具体规则ID从1开始
// 	struThermCond.dwChan = DwChannel; 	  //从1开始，0xffffffff代表获取全部通道
// 	struThermCond.byMode = 1;			//长连接模式：0- 保留（兼容不支持该功能的老设备），1- 定时模式，2-  温差模式
// 	struThermCond.wInterval = 2;		//send /2s

// 	/*
// 	1-定时模式：设备每隔一秒上传各个规则测温数据的最高温、最低温和平均温度值、温差。
// 	2-温差模式：若上一秒与下一秒的最高温或者最低温或者平均温或者温差值的温差大于等于2摄氏度，
// 				则上传最高温、最低温和平均温度值；若大于等于一个小时温差值均小于2摄氏度，则上传最高温、最低温、平均温和温差值  
// 	*/
// 	mLHandle_realtemp = NET_DVR_StartRemoteConfig(lUserId, NET_DVR_GET_REALTIME_THERMOMETRY, &struThermCond, sizeof(struThermCond), GetThermInfoCallback, this);
// 	if (mLHandle_realtemp < 0)
// 	{
// 		printf("NET_DVR_GET_REALTIME_THERMOMETRY failed, error code: %d lHandle: %d\n", NET_DVR_GetLastError(), mLHandle_realtemp);
// 		return -1;
// 	}
// 	else
// 	{
// 		printf("\033[1;32mNET_DVR_GET_REALTIME_THERMOMETRY success! lHandle: %d\033[0m\n", mLHandle_realtemp);
// 	}
//     sleep(0.1);
// 	return 0;
// }


// void CALLBACK GetThermInfoCallback(DWORD dwType, void* lpBuffer, DWORD dwBufLen, void* pUserData) 
// {   
// 	if (dwType == NET_SDK_CALLBACK_TYPE_DATA)     
// 	{         
// 		LPNET_DVR_THERMOMETRY_UPLOAD lpThermometry = new NET_DVR_THERMOMETRY_UPLOAD;         
// 		memcpy(lpThermometry, lpBuffer, sizeof(*lpThermometry));


// 		if(lpThermometry->byRuleCalibType == 0) //点测温         
// 		{             
// 			printf("点测温信息:fTemperature[%f]\n", lpThermometry->struPointThermCfg.fTemperature);  
// 			printf("debug:  thermalcam.cpp::  isCapPicture ###4\n");
// 		}


// 		if((lpThermometry->byRuleCalibType==1)||(lpThermometry->byRuleCalibType==2)) //框/线测温         
// 		{

// 			const string ftpSendImgPath = regularCapPictureAndFtpSend(LUserID, DwChannel, AlarmPath_local, ftpTempPath_thermal_service);
// 			if(ftpSendImgPath != "null"){
// 				mutexTempInfo.lock();
// 				max_thermalTemp = lpThermometry->struLinePolygonThermCfg.fMaxTemperature;
// 				min_thermalTemp = lpThermometry->struLinePolygonThermCfg.fMinTemperature;
// 				avg_thermalTemp = lpThermometry->struLinePolygonThermCfg.fAverageTemperature;
// 				diff_thermalTemp = lpThermometry->struLinePolygonThermCfg.fTemperatureDiff;
				
// 				isCapPicture = true;
// 				thermalImagePath_ftp = ftpSendImgPath;
// 				mutexTempInfo.unlock(); 
				
// 			}
  
// 		}               
// 		if (lpThermometry != NULL)         
// 		{             
// 			delete lpThermometry;             
// 			lpThermometry = NULL;         
// 		}     

// 	}   //if
// 	else if (dwType == NET_SDK_CALLBACK_TYPE_STATUS)     
// 	{    

// 		DWORD dwStatus = *(DWORD*)lpBuffer;         
// 		if (dwStatus == NET_SDK_CALLBACK_STATUS_SUCCESS)         
// 		{             
// 			printf("dwStatus:NET_SDK_CALLBACK_STATUS_SUCCESS\n");                     
// 		}         
// 		else if (dwStatus == NET_SDK_CALLBACK_STATUS_FAILED)         
// 		{             
// 			DWORD dwErrCode = *(DWORD*)((char *)lpBuffer + 4);             
// 			printf("NET_DVR_GET_MANUALTHERM_INFO failed, Error code %d\n", dwErrCode);         
// 		}     
// 	} 

// } 



// #if 1
// /*
// NET_DVR_THERMOMETRY_ALARM
// Members:
// 	dwSize  结构体大小  
// 	dwChannel  通道号  
// 	byRuleID  规则ID  
// 	byThermometryUnit  测温单位: 0- 摄氏度（℃），1- 华氏度（℉），2- 开尔文(K)  wPresetNo  预置点号  
// 	NET_PTZ_INFO struPtzInfo  PTZ坐标信息  
// 	byAlarmLevel  报警等级：0- 预警，1- 报警  
// 	byAlarmType  报警类型：0- 最高温度，1- 最低温度，2- 平均温度  
// 	byAlarmRule  报警规则：0- 大于，1- 小于  
// 	byRuleCalibType  规则标定类型：0- 点，1- 框，2- 线 

// 	NET_VCA_POINT struPoint  点测温坐标（当规则标定类型为点的时候生效）  
// 	NET_VCA_P0LYGON struRegion  区域测温坐标（当规则标定类型为框或线的时候生效） 

// 	fRuleTemperature  配置规则温度，精确到小数点后一位，取值范围：-40~1000  
// 	fCurrTemperature  当前温度，精确到小数点后一位，取值范围：-40~1000  
// 	dwPicLen  可见光图片长度  
// 	dwThermalPicLen  热成像图片长度  
// 	dwThermalInfoLen  热成像附加信息长度  

// 	char *pPicBuff  可见光图片指针，存放可见光图片数据，JPEG格式  
// 	char *pThermalPicBuff  热成像图片指针，存放热成像图片数据，JPEG格式  
// 	char *pThermalInfoBuff  热成像附加信息指针，存放热成像信息  
// 	NET_VCA_POINT struHighestPoint  线、框测温最高温度位置坐标（当规则标定类型为线、框的时候生效）  

// 	fToleranceTemperature  容差温度,精确到小数点后一位(-40-1000),（浮点数+100）  
// 	dwAlertFilteringTime  温度预警等待时间，单位：秒，范围为0-200秒，默认为0秒  
// 	dwAlarmFilteringTime  温度报警等待时间，单位：秒，范围为0-200秒，默认为0秒  
// 	dwAlertFilteringTime  温度突变记录周期，单位：秒  
// 	dwAlarmFilteringTime  温度突变值,精确到小数点后一位(大于0)  
// 	byPicTransType  图片数据传输方式：0-二进制，1-URL  
// 	byRes  保留字节 
// */
// //save img in local
// BOOL CALLBACK MessageCallback_localImg(LONG lCommand, NET_DVR_ALARMER *pAlarmer, char *pAlarmInfo, DWORD dwBufLen, void* pUser) 
// {
// 	// NET_DVR_JPEGPARA strPicPara = {0};
// 	// strPicPara.wPicQuality = 0;	//图片质量系数：0-最好，1-较好，2-一般 
// 	// strPicPara.wPicSize = 500;	//500-384*288
// 	//printf("debug:  thermalcam.cpp::  MessageCallback_localImg()\n");
// 	switch(lCommand)      
// 	{                
// 		case COMM_THERMOMETRY_ALARM: //温度预警或者温度报警         
// 		{
// 			//printf("温度预警或者温度报警 : \n");    
// 			NET_DVR_THERMOMETRY_ALARM struThermometryAlarm = {0};             
// 			memcpy(&struThermometryAlarm, pAlarmInfo, sizeof(NET_DVR_THERMOMETRY_ALARM));             
// 			if (0 == struThermometryAlarm.byRuleCalibType)             
// 			{                 
// 				printf("点测温: \n"); 
// 			}             
// 			else if (1 == struThermometryAlarm.byRuleCalibType || 2 == struThermometryAlarm.byRuleCalibType)             
// 			{
// 				//printf("线测温或者框测温: \n");
// 				const string imgName = getImageName(".jpg");  
//                 const string filePathName = AlarmPath_local + "/" + imgName;	//save local
// 				FILE *fsnapPic = NULL;
// 				fsnapPic = fopen(const_cast<char*>(filePathName.c_str()), "wb");
// 				fwrite(struThermometryAlarm.pThermalPicBuff, struThermometryAlarm.dwThermalPicLen, 1, fsnapPic);
// 				fclose(fsnapPic);
				
// 				const string currentDate = getcurrentDate();
// 				sendftp(IP_service, filePathName, alarmPath_service+"/"+currentDate, "robot001", "robot001", "./thermal_alarm.sh");

// 				const string alarmImageNamePathToService = alarmPath_service + "/" + currentDate +  "/" + imgName;
// 				pushAlarm(alarmImageNamePathToService, "imgStr", struThermometryAlarm.struHighestPoint.fX, struThermometryAlarm.struHighestPoint.fY);					//add alarm info to client
// 				//cout << "thermalcam.cpp ::MessageCallback_localImg() " << alarmImageNamePathToService << endl;
				
// 			}
// 			break;         
// 		} //case            
// 		case COMM_THERMOMETRY_DIFF_ALARM: //温差报警         
// 		{
// 			printf("温差报警 : \n");    
// 			NET_DVR_THERMOMETRY_DIFF_ALARM struThermometryDiffAlarm = {0};             
// 			memcpy(&struThermometryDiffAlarm, pAlarmInfo, sizeof(NET_DVR_THERMOMETRY_DIFF_ALARM));  
          
// 			if (0 == struThermometryDiffAlarm.byRuleCalibType)             
// 			{
// 				printf("点测温: \n");   
				      
// 			}             
// 			else if (1 == struThermometryDiffAlarm.byRuleCalibType || 2 == struThermometryDiffAlarm.byRuleCalibType)             
// 			{
// 				printf("线测温或者框测温 : \n");          
// 				int i = 0;                 
// 				int iPointNum = struThermometryDiffAlarm.struRegion[0].dwPointNum;                 
// 				for (i = 0; i < iPointNum; i++)                 
// 				{                     
// 					float fX = struThermometryDiffAlarm.struRegion[0].struPos[i].fX;                     
// 					float fY = struThermometryDiffAlarm.struRegion[0].struPos[i].fY;                     
// 					printf("测温区域1坐标点: X%d:%f,Y%d:%f;\n", iPointNum + 1, fX, iPointNum + 1, fY);                 
// 				}                 
// 				iPointNum = struThermometryDiffAlarm.struRegion[1].dwPointNum;                 
// 				for (i = 0; i < iPointNum; i++)                 
// 				{                     
// 					float fX = struThermometryDiffAlarm.struRegion[1].struPos[i].fX;                     
// 					float fY = struThermometryDiffAlarm.struRegion[1].struPos[i].fY;                     
// 					printf("测温区域2坐标点: X%d:%f,Y%d:%f;\n", iPointNum + 1, fX, iPointNum + 1, fY);                 
// 				}          
// 			}

// 			break;         
// 		}             
// 		default:
// 		{          
// 			printf("其他报警，报警信息类型: %d\n", lCommand);             
// 			break;
// 		}  
// 	}//switch   
// 	return TRUE; 
// }
// #endif



/*
* get imgBuf
* inLUserID
    [in]
* channel
    [in]
* imgBuff
    [in] save imgData buff
* imgBuffLen
    [in] imgData buff size
* lpSizeReturned
    [out] return imgData size
*/
void capPicture_v3(const int inLUserID, const int channel, char *imgBuff, int imgBuffLen)
{
    int aaa = 0;
    return ;
    NET_DVR_JPEGPICTURE_WITH_APPENDDATA strPicPara;

    // int iRet = NET_DVR_CaptureJPEGPicture_WithAppendData(inLUserID, channel, &strPicPara );
    // int len = strPicPara.dwJpegPicHeight;
    // printf(".... %d\n", len);
    // if (!iRet)
    // {
    //     printf("pyd1---NET_DVR_CaptureJPEGPicture error, %d\n", NET_DVR_GetLastError());
    //     return -1;       //-1
    // }

    // return 0;
    // LPNET_DVR_JPEGPARA strPicPara2;
    // strPicPara2->wPicSize = 0;
    // strPicPara2->wPicSize = 500;

    // char imgBuff[1000000];
    // LPDWORD reLen;
    // iRet = NET_DVR_CaptureJPEGPicture_NEW(inLUserID, channel, strPicPara2 , imgBuff, sizeof(imgBuff), reLen);
    // int len = strPicPara2.dwJpegPicHeight;
    // printf(".... %d\n", len);
    // if (!iRet)
    // {
    //     printf("pyd1---NET_DVR_CaptureJPEGPicture error, %d\n", NET_DVR_GetLastError());
    //     return -1;       //-1
    // }
//     NET_DVR_JPEGPARA strPicPara = {0};
//     //strPicPara.wPicQuality = 2;
//     //strPicPara.wPicSize = 0;

//     strPicPara.wPicQuality = 0;  //图片质量系数：0-最好，1-较好，2-一般 
//     strPicPara.wPicSize = 500;   //0:352x288, 1:176x144, 2:704x576, 3:1600x1200, 4:800x600, ......   500:384x288

//     int iRet;

// return 0;
//     //unsigned int* 
//     LPDWORD lpSizeReturned;
//     iRet = NET_DVR_CaptureJPEGPicture_NEW(inLUserID, channel, &strPicPara, imgBuff, imgBuffLen, lpSizeReturned );
//     if (!iRet)
//     {
//         printf("pyd1---NET_DVR_CaptureJPEGPicture error, %d\n", NET_DVR_GetLastError());
//         return -1;       //-1
//     }
//     std::cout << lpSizeReturned << std::endl;
//     printf("......%d\n", sizeof(lpSizeReturned));

    // FILE *fp = NULL;
    // string imgpath = "/home/ljl/Pictures/" + getLocalTime_self() + ".jpg";
    // fp = fopen(const_cast<char*>(imgpath.c_str() ), "wb");
    // fwrite(imgBuff, imgLen, 1, fp);
    // fclose(fp);
}

#endif

